package springboot.demo.controller;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springboot.demo.annotation.NotProfile;
import springboot.demo.bean.Chapter;
import springboot.demo.bean.Comment;
import springboot.demo.bean.Novel;
import springboot.demo.dao.ChapterRepository;
import springboot.demo.dao.CommentMapper;
import springboot.demo.dao.NovelMapper;
import springboot.demo.service.NovelService;
import springboot.demo.system.websocketByNetty.ChannelSupervise;
import springboot.demo.util.CommandUtil;
import springboot.demo.util.ExportExcel;
import springboot.demo.dto.ResultDTO;
import springboot.demo.util.ThreadPoolExecutorWithTraceid;

import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

@RestController
@NotProfile("simple")
@RequestMapping("/demo")
public class DemoController {

	@Autowired
	NovelMapper novelMapper;

	@Autowired
	NovelService novelService;

	@Autowired
	ChapterRepository chapterRepository;

	@Autowired
	ApplicationContext applicationContext;

	@Autowired
	CommentMapper commentMapper;

	private static Logger LOGGER = LoggerFactory.getLogger(DemoController.class);

	@GetMapping("/v1/testjpa")
	public ResultDTO testjpa(Integer id) {
		LOGGER.info("testjpa方法入参 - id: {}", id);
		Optional<Chapter> chapter = chapterRepository.findById(id);
		LOGGER.info("data:{}", JSON.toJSONString(chapter));
		return ResultDTO.success(chapter);
	}

	@GetMapping("/v1/hello")
	public String get(HttpServletRequest request) {
		LOGGER.info("get方法入参 - request: {}", request);
		DispatcherServlet d;
		WebMvcConfigurationSupport w;
		System.out.println(request.getServletPath());
		ServletContext servletContext = request.getServletContext();
		System.out.println(request.getServletContext().getServletContextName());
		LOGGER.info("Hello spring");

		novelService.list();
		return "Hello spring";
	}

	/**
	 * 测试sql注入
	 * 直接使用用户输入的参数，xml中使用${}拼接SQL会有注入风险
	 * 例如query为-1 or novel_name='eva'
	 * @param query
	 * @return
	 */
	@GetMapping("/v1/testSqlInject")
	public String testSqlInject(String query){
		LOGGER.info("testSqlInject方法入参 - query: {}", query);
		LOGGER.info(query);
		return novelService.testSqlInject(query).getNovelName();
	}

	/**
	 * 测试非事务方法调用事务方法，事务不生效
	 * @param id
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/v1/testTran")
	public String testTran(int id) throws Exception {
		LOGGER.info("testTran方法入参 - id: {}", id);
		return novelService.testTran(id).getNovelName();
	}

	@GetMapping("/v1/testIncr")
	public String testIncr(int id) throws Exception {
		LOGGER.info("testIncr方法入参 - id: {}", id);
		return novelService.incrementById(id).getNovelName();
	}

	@RequestMapping("/v1/sendMessageByNetty")
	public void sendMessageByNetty(String message, String id) {
		LOGGER.info("sendMessageByNetty方法入参 - message: {}, id: {}", message, id);
		ChannelSupervise.send2All(new TextWebSocketFrame(message));
	}

	@RequestMapping("/v1/getComment")
	public ResultDTO getComment(int id) {
		LOGGER.info("getComment方法入参 - id: {}", id);
		Comment comment = commentMapper.selectById(id);
		LOGGER.info("comment:{}", JSON.toJSONString(comment));
		return ResultDTO.success(comment);
	}

	@RequestMapping("/v1/updateNovel")
	public String updateNovel(Integer id, String name) {
		LOGGER.info("updateNovel方法入参 - id: {}, name: {}", id, name);
		Novel novel = new Novel();
		novel.setId(id);
		novel.setNovelName(name);
		novelMapper.updateById(novel);
		return "200";
	}

	@RequestMapping("/v1/exportExcel")
	public void exportExcel(HttpServletResponse response) {
		LOGGER.info("exportExcel方法入参 - response: {}", response);
		LOGGER.info("start export excel");
		ExportExcel.export(response);
	}

	@RequestMapping("/v1/shutdown")
	public String shutdown(){
		LOGGER.info("shutdown方法入参 - 无参数");
		try {
			LOGGER.info("shutdown the server");
			LOGGER.info(CommandUtil.run("poweroff"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "shutdown ok";
	}

	/**
	 * 测试多线程中添加调用链
	 * @return
	 */
	@RequestMapping("/v1/testTraceId")
	public String testTraceId(){
		LOGGER.info("testTraceId方法入参 - 无参数");
		LOGGER.info("OUT");
		ThreadPoolExecutorWithTraceid threadPool = new ThreadPoolExecutorWithTraceid(10,10,10, TimeUnit.SECONDS,new LinkedBlockingQueue<>(10));
		threadPool.execute(()->{
			Logger LOGGER = LoggerFactory.getLogger(ThreadPoolExecutorWithTraceid.class);
			LOGGER.info("aaaa");
		});

		threadPool.submit(()->{
			Logger LOGGER = LoggerFactory.getLogger(ThreadPoolExecutorWithTraceid.class);
			LOGGER.info("bbbb");
		});
		return "shutdown ok";
	}

}
